<?php

namespace App\Repository;

use App\Entity\AdminUser;
use App\Utils\Base\FilterBase;
use App\Utils\Enum\RedisKeyEnum;
use App\Service\RedisService;
use App\Utils\Filter\Admin\User\AdminUserFilter;
use App\Utils\Traits\FilterTrait;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @method AdminUser|null find($id, $lockMode = null, $lockVersion = null)
 * @method AdminUser|null findOneBy(array $criteria, array $orderBy = null)
 * @method AdminUser[]    findAll()
 * @method AdminUser[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class AdminUserRepository extends ServiceEntityRepository {
    use FilterTrait;

    private $redis;

    public function __construct (ManagerRegistry $registry, RedisService $redis) {
        parent::__construct($registry, AdminUser::class);
        $this->redis = $redis->redis;
    }

    /**
     * 以数组的形式返回所有数据
     * @return array|mixed
     */
    public function findAllToArray () {
        $result = [];

        $redis_key = RedisKeyEnum::REDIS_ADMIN_USER_FIND_ALL_BY_ARRAY_KEY;
        $redis_admin_user_data = $this->redis->get($redis_key);
        if (is_null($redis_admin_user_data)) {
            $objs = $this->findAll();
            foreach ($objs as $obj) {
                $result[$obj->getId()] = $obj->getUsername();
            }
            $this->redis->setex($redis_key, 600, serialize($result));
        } else {
            $result = unserialize($redis_admin_user_data);
        }

        return $result;
    }

    /**
     * 根据id获取用户信息
     * @param $id
     * @return array
     * @throws \Exception
     */
    public function getInfoById ($id) {
        return $this->createQueryBuilder('a')
            ->select('a.id,a.username,a.nickname,a.contact,a.email,a.admin_user_group_id,a.avatar,a.motto')
            ->where('a.id = :id')
            ->setParameter('id', $id)
            ->getQuery()
            ->getArrayResult();
    }

    /**
     * 获取字段和对应值并且不等于ID值的数据
     * @param $field
     * @param $value
     * @param $id
     * @return mixed
     * @throws \Exception
     */
    public function findOneByFieldAndNotId ($field, $value, $id) {
        return $this->createQueryBuilder('a')
            ->select('a.id,a.username,a.email,a.admin_user_group_id')
            ->where('a.id != :id')
            ->andWhere('a.'.$field.' = :field')
            ->setParameter('id', $id)
            ->setParameter('field', $value)
            ->getQuery()
            ->getOneOrNullResult();
    }

    /**
     * 根据用户名返回用户ID集合
     * @param $admin_user
     * @return array
     * @throws \Exception
     */
    public function getAdminUserIdsByUsername ($admin_user) {
        return $this->createQueryBuilder('a')
            ->select('a.id')
            ->where('a.username like :username')
            ->setParameter('username', '%'.$admin_user.'%')
            ->getQuery()
            ->getArrayResult();
    }

    /**
     * 查询
     * @param array $params
     * @param array $select
     * @return array|int|string
     */
    public function search ($params = [], $select = []) {
        $page = $params['page'] ?? 1;
        $limit = $params['limit'] ?? 10;
        $query_builder = $this->filter(new AdminUserFilter($params))
            ->setFirstResult(($page - 1) * $limit)
            ->setMaxResults($limit)
            ->orderBy(FilterBase::ALIAS.'.id', 'DESC');
        if ($select) {
            $query_builder->select(implode(',', $select));
        } else {
            $query_builder->select(FilterBase::ALIAS.'.id,'.FilterBase::ALIAS.'.email,'.FilterBase::ALIAS.'.username,'.FilterBase::ALIAS.'.nickname,'.FilterBase::ALIAS.'.contact,'.FilterBase::ALIAS.'.admin_user_group_id,'.FilterBase::ALIAS.'.avatar,'.FilterBase::ALIAS.'.created_at');
        }

        return $query_builder->getQuery()->getArrayResult();
    }

    /**
     * 获取查询count
     * @param array $params
     * @return int|mixed|string
     */
    public function searchTotal ($params = []) {
        return $this->filter(new AdminUserFilter($params))
            ->select('count('.FilterBase::ALIAS.'.id) as total')
            ->getQuery()
            ->getSingleScalarResult();
    }

    /**
     * 获取用户最新的多条数据
     * @param int $limit
     * @return array|int|string
     */
    public function getWorkplaceTopAdminUsers ($limit = 5) {
        return $this->createQueryBuilder('a')
            ->select('a.id,a.username,a.avatar')
            ->setFirstResult(0)
            ->setMaxResults($limit)
            ->orderBy('a.id', 'DESC')
            ->getQuery()
            ->getArrayResult();
    }
}
